package com.qf;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitOperations;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.amqp.RabbitTemplateConfigurer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Rabbitmq2Application {

    public static void main(String[] args) {
        SpringApplication.run(Rabbitmq2Application.class, args);
    }


    @Bean
    public RabbitTemplate rabbitTemplate(RabbitTemplateConfigurer configurer, ConnectionFactory connectionFactory) {
        RabbitTemplate template = new RabbitTemplate();
        configurer.configure(template, connectionFactory);

        //设置confirm监听
        template.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /*
                CorrelationData correlationData ： 回退的消息数据，如果发送消息时没有额外设置，那么这个就是你发送的那条消息数据
                boolean ack:是否到达交换机
                String cause:如果没到达交换机，原因描述
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if (!ack){
                    //消息没到达交换机 -- 重试
                    ReturnedMessage returned = correlationData.getReturned();
                    Message message = returned.getMessage();
                    String exchange = returned.getExchange();
                    String routingKey = returned.getRoutingKey();

                    template.send(exchange,routingKey,message);
                }else{
                    //消息到达了交换机 -- 啥也不干
                    System.out.println("消息正常到达交换机");
                }
            }
        });

        //设置returns监听
        template.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            /*
                当消息从交换机路由到队列失败时，才会触发这个方法，否则这个方法不触发
             */
            @Override
            public void returnedMessage(ReturnedMessage returned) {

                System.out.println("消息到达队列失败，触发回退重试....");

                Message message = returned.getMessage();
                String exchange = returned.getExchange();
                String routingKey = returned.getRoutingKey();

                //失败重发
                template.send(exchange,routingKey,message);
            }
        });


        return template;
    }

}
